import json
import re
import serial
import logging
import math
from bins.vehiclelogger import SharedVariable
from src.connection.SerialBase import SerialBase
from src.connection.EthernetBase import EthernetBase

logger = logging.getLogger(__name__)
kk = re.compile(r'\d+\.?\d+|\d+|-\d+\.?\d+')
# 编译正则表达式，用以检索串口报文数据，可以加速处理串口报文


class Connect:
    def __init__(self, ser: str = None, serPC: str = None):
        self.x_pre = 0
        self.y_pre = 0
        self.i = 0
        self.ser = {
            "name": ser,
            "Baud-rate": 115200,
            "timeout": "0.4"
        }
        self.serPC = {
            "name": serPC,
            "Baud-rate": 115200,
            "timeout": "0.4"
        }
        self.ser_connect = None
        self.serPC_connect = None
        self.SharedVariable = SharedVariable()

    def connect(self) -> bool:
        loadconfig = json.loads(open("./conf/serial_port.json", "r").read())
        if self.ser["name"] is None:
            self.ser = loadconfig["ser"]
            self.serPC = loadconfig["serPC"]
        try:
            if loadconfig["ser"]["model"] == "serial":
                self.ser_connect = SerialBase(self.ser["name"], self.ser["Baud-rate"], self.ser["timeout"])
            else:
                self.ser_connect = EthernetBase()
                self.ser_connect.loadConfig(loadconfig["ser"])

            if loadconfig["serPC"]["model"] == "serial":
                self.serPC_connect = SerialBase(self.serPC["name"], self.serPC["Baud-rate"], self.serPC["timeout"])
            else:
                self.serPC_connect = EthernetBase()
                self.serPC_connect.loadConfig(loadconfig["serPC"])
            self.ser_connect.send('Ready \r\n')
            return True
        except:
            logger.error("Serial port connection failed.")
            return False

    def disconnect(self) -> bool:
        try:
            self.ser_connect.close()
            self.serPC_connect.close()
            return True
        except:
            return False

    def sendtoPC(self, data: str) -> bool:
        try:
            self.serPC_connect.send(data)
            return True
        except:
            return False

    def getPCinput(self) -> str:
        PCorder = self.serPC_connect.receive()
        return PCorder

    def get_car_state(self, send: int = 0) -> (dict, bool):
        if send == 0:
            dataraw = self.ser_connect.receive()
            self.serPC_connect.send(dataraw)
            print(dataraw)
        else:
            dataraw = self.ser_connect.receive()
        self.SharedVariable.update_data(dataraw)

    def car_control(self, thr: float, brake: float, steer: float) -> bool:
        try:
            self.ser_connect.send(
                '$,' + str(round(thr, 3)) + ',' + str(round(brake, 3)) + ',' + str(round(steer, 3)) + ',\r\n')
            return True
        except:
            return False